/*
 * Created on 24/05/2005
 */
package util;

import java.awt.Canvas;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * @author Diego Sanchez Gallo.
 */
public class TelaVertices extends JFrame {

	private static final int WINDOW_WIDTH = 800;
	private static final int WINDOW_HEIGHT = 600;

	private JTextField textFieldNomeEstab;
	private JTextField textFieldCaminhoXML;
	private JTextField textFieldCaminhoImagem;
	private JTextField textFieldNomeGrafo;
	private JTextField textFieldNivelGrafo;
	private JTextField textFieldNomeVertice;
	private JTextField textFieldAndar;
	private JTextField textFieldX;
	private JTextField textFieldY;
	private JComboBox comboBoxTipoVertice;
	private JDialog dialogInicio;

	private double x = 0, y = 0, andar = 0;

	private Canvas canvas;
	private Image imagem;
	private File xmlGrafo;

	private boolean primeiroVertice = true;
	
	private ArrayList nomesVertices = new ArrayList();

	public TelaVertices() {
		super();

		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
		setTitle("Gerador XML - Tela V�rtices");

		// Panel Esquerdo
		JPanel panelEsquerdo = new JPanel();
		panelEsquerdo.setLayout(new BoxLayout(panelEsquerdo, BoxLayout.Y_AXIS));

		canvas = new CanvasImagem();
		canvas.setSize(500, 500);

		JPanel panelEsquerdoInferior = new JPanel();
		panelEsquerdoInferior.setLayout(new BoxLayout(panelEsquerdoInferior,
				BoxLayout.X_AXIS));
		JLabel labelCaminhoImagem = new JLabel("Imagem: ");
		textFieldCaminhoImagem = new JTextField();
		JButton buttonCarregar = new JButton("OK");
		buttonCarregar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				carregarImagem();
			}
		});
		panelEsquerdoInferior.add(labelCaminhoImagem);
		panelEsquerdoInferior.add(textFieldCaminhoImagem);
		panelEsquerdoInferior.add(buttonCarregar);
		panelEsquerdoInferior.setMaximumSize(new Dimension(2000, 100));

		panelEsquerdo.add(canvas);
		panelEsquerdo.add(panelEsquerdoInferior);

		//Panel Direito
		JPanel panelDireito = new JPanel();
		panelDireito.setLayout(new BoxLayout(panelDireito, BoxLayout.Y_AXIS));

		JPanel panelDireitoSuperior = new JPanel();
		panelDireitoSuperior.setLayout(new GridLayout(2, 2));
		JLabel labelNomeGrafo = new JLabel("Nome: ");
		textFieldNomeGrafo = new JTextField();
		JLabel labelNivelGrafo = new JLabel("N�vel: ");
		textFieldNivelGrafo = new JTextField();
		panelDireitoSuperior.add(labelNomeGrafo);
		panelDireitoSuperior.add(textFieldNomeGrafo);
		panelDireitoSuperior.add(labelNivelGrafo);
		panelDireitoSuperior.add(textFieldNivelGrafo);
		panelDireitoSuperior.setBorder(BorderFactory.createEmptyBorder(15, 5,
				50, 5));

		JPanel panelDireitoCentro = new JPanel();
		panelDireitoCentro.setLayout(new BoxLayout(panelDireitoCentro,
				BoxLayout.Y_AXIS));

		JPanel panelDireitoCentroInfo = new JPanel();
		panelDireitoCentroInfo.setLayout(new GridLayout(2, 2));
		JLabel labelNomeVertice = new JLabel("Nome: ");
		textFieldNomeVertice = new JTextField();
		JLabel labelTipoVertice = new JLabel("Tipo: ");
		comboBoxTipoVertice = new JComboBox();
		comboBoxTipoVertice.addItem(new String("cruzamento"));
		comboBoxTipoVertice.addItem(new String("final"));
		comboBoxTipoVertice.addItem(new String("ponte"));
		comboBoxTipoVertice.addItem(new String("submapa"));
		panelDireitoCentroInfo.add(labelNomeVertice);
		panelDireitoCentroInfo.add(textFieldNomeVertice);
		panelDireitoCentroInfo.add(labelTipoVertice);
		panelDireitoCentroInfo.add(comboBoxTipoVertice);

		JPanel panelDireitoCentroLocalizacao = new JPanel();
		panelDireitoCentroLocalizacao.setLayout(new GridLayout(3, 2));
		panelDireitoCentroLocalizacao.setBorder(BorderFactory
				.createCompoundBorder(BorderFactory
						.createTitledBorder("Localiza��o: "), BorderFactory
						.createEmptyBorder(5, 5, 10, 5)));
		JLabel labelAndar = new JLabel("Andar: ");
		textFieldAndar = new JTextField();
		JLabel labelX = new JLabel("X: ");
		textFieldX = new JTextField();
		JLabel labelY = new JLabel("Y: ");
		textFieldY = new JTextField();
		panelDireitoCentroLocalizacao.add(labelAndar);
		panelDireitoCentroLocalizacao.add(textFieldAndar);
		panelDireitoCentroLocalizacao.add(labelX);
		panelDireitoCentroLocalizacao.add(textFieldX);
		panelDireitoCentroLocalizacao.add(labelY);
		panelDireitoCentroLocalizacao.add(textFieldY);
		panelDireitoCentroLocalizacao.setBorder(BorderFactory
				.createCompoundBorder(BorderFactory
						.createTitledBorder("Localiza��o: "), BorderFactory
						.createEmptyBorder(5, 5, 20, 5)));

		JButton buttonAdicionarVertice = new JButton("Adicionar");
		buttonAdicionarVertice
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						adicionarVertice();
					}
				});
		buttonAdicionarVertice.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createEmptyBorder(15, 0, 15, 0),
				buttonAdicionarVertice.getBorder()));

		panelDireitoCentro.add(panelDireitoCentroInfo);
		panelDireitoCentro.add(panelDireitoCentroLocalizacao);
		panelDireitoCentro.add(buttonAdicionarVertice);
		panelDireitoCentro.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("V�RTICES"), BorderFactory
						.createEmptyBorder(5, 5, 0, 5)));

		JButton buttonContinuar = new JButton("Continuar");
		buttonContinuar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				continuar();
			}
		});
		buttonContinuar.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createEmptyBorder(15, 0, 0, 0), buttonContinuar
						.getBorder()));

		panelDireito.add(panelDireitoSuperior);
		panelDireito.add(panelDireitoCentro);
		panelDireito.add(buttonContinuar);
		panelDireito.setBorder(BorderFactory.createTitledBorder("GRAFO"));
		panelDireito.setMaximumSize(new Dimension(250, 500));

		Container container = getContentPane();
		container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
		container.add(panelEsquerdo);
		container.add(panelDireito);
	}

	public void carregarImagem() {
		File file = new File(textFieldCaminhoImagem.getText());
		try {
			imagem = ImageIO.read(file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		canvas.repaint();
	}

	public void adicionarVertice() {
		try {
			if (primeiroVertice) {
				primeiroVertice = false;
				escreveTagGrafoXML();
				textFieldNomeGrafo.setEnabled(false);
				textFieldNivelGrafo.setEnabled(false);
			}
			escreveTagVertice();
		} catch (IOException e) {
			//TODO Auto-generated catch block
			e.printStackTrace();
		}
		nomesVertices.add(textFieldNomeVertice.getText());
	}

	public void continuar() {
		if (primeiroVertice) {
			JOptionPane.showMessageDialog(this,
					"� necess�rio pelo menos 1 v�rtice!");
		} else {
			try {
				escreveTagArcos();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			TelaArcos telaArcos = new TelaArcos(xmlGrafo, imagem, nomesVertices);
			telaArcos.pack();
			telaArcos.setVisible(true);
			this.dispose();
		}
	}

	public void escreveTagGrafoXML() throws IOException {
		StringBuffer buffer = new StringBuffer();
		buffer.append("    <grafo nivelHierarquico=\"");
		buffer.append(textFieldNivelGrafo.getText());
		buffer.append("\" nome=\"");
		buffer.append(textFieldNomeGrafo.getText());
		buffer.append("\">\n");
		buffer.append("        <vertices>\n");

		FileOutputStream fos = new FileOutputStream(xmlGrafo, true);
		fos.write(buffer.toString().getBytes());
		fos.flush();
		fos.close();
	}

	public void escreveTagVertice() throws IOException {
		StringBuffer buffer = new StringBuffer();
		buffer.append("            <vertice nome=\"");
		buffer.append(textFieldNomeVertice.getText());
		buffer.append("\" tipo=\"");
		buffer.append((String) comboBoxTipoVertice.getSelectedItem());
		buffer.append("\" x=\"");
		buffer.append(textFieldX.getText());
		buffer.append("\" y=\"");
		buffer.append(textFieldY.getText());
		buffer.append("\" andar=\"");
		buffer.append(textFieldAndar.getText());
		buffer.append("\" />\n");

		FileOutputStream fos = new FileOutputStream(xmlGrafo, true);
		fos.write(buffer.toString().getBytes());
		fos.flush();
		fos.close();
	}

	public void escreveTagArcos() throws IOException {
		StringBuffer buffer = new StringBuffer();
		buffer.append("        </vertices>\n");
		buffer.append("        <arcos>\n");

		FileOutputStream fos = new FileOutputStream(xmlGrafo, true);
		fos.write(buffer.toString().getBytes());
		fos.flush();
		fos.close();
	}

	/**
	 * @param xmlGrafo
	 *            The xmlGrafo to set.
	 */
	public void setXmlGrafo(File xmlGrafo) {
		this.xmlGrafo = xmlGrafo;
	}

	public void inicializar() {
		dialogInicio = new JDialog(this, "Gerador XML - Tela In�cio");

		JLabel labelNomeEstab = new JLabel("Nome Estabelecimento: ");
		JLabel labelCaminhoXML = new JLabel("Caminho XML: ");

		textFieldNomeEstab = new JTextField();
		textFieldCaminhoXML = new JTextField();

		JButton buttonContinuarDialog = new JButton("Continuar");
		buttonContinuarDialog
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						continuarDialog();
					}
				});
		buttonContinuarDialog.setMnemonic('C');

		dialogInicio.getContentPane().setLayout(new GridLayout(3, 2));
		dialogInicio.getContentPane().add(labelNomeEstab);
		dialogInicio.getContentPane().add(textFieldNomeEstab);
		dialogInicio.getContentPane().add(labelCaminhoXML);
		dialogInicio.getContentPane().add(textFieldCaminhoXML);
		dialogInicio.getContentPane().add(buttonContinuarDialog);

		dialogInicio.setDefaultCloseOperation(EXIT_ON_CLOSE);
		dialogInicio.getRootPane().setDefaultButton(buttonContinuarDialog);

		dialogInicio.pack();
		dialogInicio.setVisible(true);
	}

	private void continuarDialog() {
		try {
			xmlGrafo = new File(textFieldCaminhoXML.getText());
			boolean ok = true;
			if (!xmlGrafo.createNewFile()) {
				if (JOptionPane.showConfirmDialog(this,
						"ARQUIVO J� EXISTE! Sobrescrever?",
						"Arquivo j� existe", JOptionPane.YES_NO_OPTION,
						JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
					ok = false;
				}
			}
			if (ok) {
				escreveTagEstabelecimentoXML();
				dialogInicio.dispose();
			} else {
				JOptionPane.showMessageDialog(this,
						"Por favor, escolha outro nome de arquivo.");
			}
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this,
					"Erro de I/O na escrita do arquivo.");
			e.printStackTrace();
		}
	}

	private void escreveTagEstabelecimentoXML() throws IOException {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<estabelecimento nome=\"");
		buffer.append(textFieldNomeEstab.getText());
		buffer.append("\">\n");

		FileOutputStream fos = new FileOutputStream(xmlGrafo);
		fos.write(buffer.toString().getBytes());
		fos.flush();
		fos.close();
	}

	public class CanvasImagem extends Canvas implements MouseListener,
			MouseMotionListener, MouseWheelListener {

		double hmult = 1;
		int xprev = 0;
		int yprev = 0;
		int xpos = 0;
		int ypos = 0;

		public CanvasImagem() {
			addMouseListener(this);
			addMouseMotionListener(this);
			addMouseWheelListener(this);
		}

		public void paint(Graphics graphics) {
			if (imagem != null) {
				graphics.drawImage(imagem, xpos, ypos,(int)(imagem.getWidth(this) * hmult),  (int)(imagem.getHeight(this) * hmult), null);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
		 */
		public void mouseClicked(MouseEvent e) {
			// TODO Auto-generated method stub
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
		 */
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
		 */
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
		 */
		public void mousePressed(MouseEvent e) {
			if (e.getButton() == MouseEvent.BUTTON3) {
				textFieldX.setText(String.valueOf((int)((e.getX() - xpos) / hmult)));
				textFieldY.setText(String.valueOf((int)((e.getY() - ypos) / hmult)));
			}
			xprev = e.getX();
			yprev = e.getY();
			e.consume();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
		 */
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
		 */
		public void mouseDragged(MouseEvent e) {
			int xMouse = e.getX();
			int yMouse = e.getY();

			xpos += xMouse - xprev;
			ypos += yMouse - yprev;

			xprev = xMouse;
			yprev = yMouse;
			ajustaXPosYPos();
			repaint();
			// System.out.println("posicao (" + xpos + ", " + ypos + ")");
			e.consume();

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
		 */
		public void mouseMoved(MouseEvent arg0) {
			// TODO Auto-generated method stub

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
		 */
		public void mouseWheelMoved(MouseWheelEvent e) {
			if (e.getWheelRotation() > 0) {
				ampliar();
			} else if (e.getWheelRotation() < 0) {
				diminuir();
			}
			e.consume();
		}

		public void ampliar() {
			hmult *= 1.2;
			ajustaXPosYPos();
			repaint();
		}

		public void diminuir() {
			hmult /= 1.2;
			ajustaXPosYPos();
			repaint();
		}

		private void ajustaXPosYPos() {
			int xLimiteMax = imagem.getWidth(this) * hmult > getBounds().getWidth() ? 0 : (int) (getBounds().getWidth() - imagem.getWidth(this) * hmult);
			int xLimiteMin = imagem.getWidth(this) * hmult > getBounds().getWidth() ? (int) (getBounds().getWidth() - imagem.getWidth(this) * hmult) : 0;
			int yLimiteMax = imagem.getHeight(this) * hmult > getBounds().getHeight() ? 0 : (int) (getBounds().getHeight() - imagem.getHeight(this) * hmult);
			int yLimiteMin = imagem.getHeight(this) * hmult > getBounds().getHeight() ? (int) (getBounds().getHeight() - imagem.getHeight(this) * hmult) : 0;

			if (xpos > xLimiteMax)
				xpos = xLimiteMax;
			if (xpos < xLimiteMin)
				xpos = xLimiteMin;
			if (ypos > yLimiteMax)
				ypos = yLimiteMax;
			if (ypos < yLimiteMin)
				ypos = yLimiteMin;

		}
	}

	public static void main(String[] args) {
		TelaVertices telaVertices = new TelaVertices();
		telaVertices.pack();
		telaVertices.setVisible(true);
		telaVertices.inicializar();
	}

}